package com.secxiot.consumer.task.controller;


import com.alibaba.fastjson.JSONObject;
import com.secxiot.common.constant.ServerStatusEnum;
import com.secxiot.common.entity.ResultVo;
import com.secxiot.common.exception.BaseException;
import com.secxiot.common.exception.BaseRuntimeException;
import com.secxiot.common.utils.MapConvertUtil;
import com.secxiot.common.utils.RedisUtil;
import com.secxiot.consumer.task.feign.TaskClient;
import com.secxiot.provider.task.dto.TaskDto;
import com.secxiot.provider.task.dto.TaskSosDto;
import com.secxiot.provider.task.dto.TaskTransferListDto;
import com.secxiot.provider.task.dto.TaskVisitDto;
import com.secxiot.provider.task.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = {"任务相关"})
@RestController
@RequestMapping("/tasks")
public class TaskConsumerController {

    @Autowired
    private TaskClient taskClient;

    @Autowired
    private RedisUtil redisUtil;

    private final static long LOCATION = 24 * 60 * 60;

    private static Logger log = LoggerFactory.getLogger(TaskConsumerController.class);

    @ApiOperation(value = "获取用户给定时间段任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "form", dataType = "long"),
            @ApiImplicitParam(name = "pageNo", value = "页码，0开始", paramType = "form", required = true, dataType = "long"),
            @ApiImplicitParam(name = "pageSize", value = "请求数量", paramType = "form", required = true, dataType = "long"),
            @ApiImplicitParam(name = "since", value = "开始时间", paramType = "form", required = true, dataType = "date-time"),
            @ApiImplicitParam(name = "last", value = "结束时间，不传默认到当前最新", paramType = "form", required = false, dataType = "date")
    })
    @GetMapping
    public ResultVo<TaskHomeVo> listUnfinishedByUserIdAndTime(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize,
            @RequestParam(value = "since", required = true) Date since,
            @RequestParam(value = "last", required = false) Date last) {
        return new ResultVo<>(taskClient.listUnfinishedByUserIdAndTime(userId, pageNo, pageSize, since, last));
    }

    /**
     * 发布任务
     *
     * @param taskDto 任务内容
     * @return
     */
    @ApiOperation(value = "发布普通任务", httpMethod = "POST")
    @PostMapping
    public ResultVo<Long> publish(@RequestBody TaskDto taskDto) {
        return new ResultVo<Long>(taskClient.publish(taskDto));
    }

    /**
     * 发布交接任务
     *
     * @param taskTransferListDto 交接任务内容
     * @return 任务id
     */
    @ApiOperation(value = "发布交接任务", httpMethod = "POST")
    @PostMapping("transfer")
    public ResultVo<Long> publishTransfer(@RequestBody TaskTransferListDto taskTransferListDto) {
        return new ResultVo<Long>(taskClient.publish(taskTransferListDto));
    }

    /**
     * 发布SOS任务
     *
     * @param sosDto SOS任务内容
     * @return 任务id
     */
    @ApiOperation(value = "发布SOS任务", httpMethod = "POST")
    @PostMapping("sos")
    public ResultVo<Long> publishSosTask(@RequestBody TaskSosDto sosDto) {
        return new ResultVo<>(taskClient.publishSosTask(sosDto));
    }

    /**
     * 发布出诊任务
     *
     * @param taskVisitDto SOS出诊任务内容
     * @return 任务id
     */
    @ApiOperation(value = "发布出诊任务", httpMethod = "POST")
    @PostMapping("visit")
    public ResultVo<Long> publishSosVisit(@RequestBody TaskVisitDto taskVisitDto) throws BaseException {
        return new ResultVo<>(taskClient.publishSosVisit(taskVisitDto));
    }

    /**
     * 获取任务状态信息
     *
     * @param userId 用户id
     * @return 任务状态信息
     */
    @ApiOperation(value = "获取患者SOS任务状态信息", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "患者id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "taskId", value = "任务id，医护用户必须传", required = false, paramType = "query", dataType = "Long")
    })
    @GetMapping("/sos/status")
    public ResultVo<TaskSOSStatusVo> getTaskConfirmStatusById(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "taskId", required = false) Long taskId) {
        try {
            return new ResultVo<>(taskClient.getSOSTaskStatusByPatientId(userId, taskId));
        } catch (BaseException e) {
            return new ResultVo<>(e);
        }
    }

    /**
     * 更新任务状态信息
     *
     * @param userId        用户id
     * @param taskId        任务id
     * @param confirmStatus 状态
     * @return 任务状态信息
     * @throws BaseException
     */
    @ApiOperation(value = "更新任务状态", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "form", dataType = "Long"),
            @ApiImplicitParam(name = "taskId", value = "任务id", required = true, paramType = "form", dataType = "Long"),
            @ApiImplicitParam(name = "confirmStatus", value = "状态，字典00008", required = true, paramType = "form", dataType = "String")
    })
    @PostMapping("status")
    ResultVo<TaskStatusUpdateVo> updateStatus(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "taskId", required = true) Long taskId,
            @RequestParam(value = "confirmStatus", required = true) String confirmStatus
    ) throws BaseException {
        TaskStatusUpdateVo updateVo = taskClient.updateStatus(userId, taskId, confirmStatus);
        return new ResultVo<>(updateVo);
    }

    /**
     * 获取患者检测数据模板
     *
     * @param deptId 部门id
     * @return 患者检测数据模版列表
     */
    @ApiOperation(value = "获取患者检测数据模版", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/transfer/temp")
    public ResultVo<List<TaskTempVo>> getTaskTemp(@RequestParam Long deptId) {
        List<TaskTempVo> list = taskClient.getTaskTemp(deptId);
        return new ResultVo<List<TaskTempVo>>(list);
    }

    @ApiOperation(value = "获取已发布任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageNo", value = "页码", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "条数", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/published")
    public ResultVo<List<TaskDisplayVo>> getPublishedList(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize) {

        return new ResultVo<List<TaskDisplayVo>>(taskClient.getPublishedList(userId, pageNo, pageSize));
    }

    @ApiOperation(value = "获取我的科室任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId", value = "部门id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageNo", value = "页码", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "条数", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/depart")
    public ResultVo<List<TaskDisplayVo>> getDepartmentList(
            @RequestParam(value = "deptId", required = true) Long deptId,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize) {

        return new ResultVo<List<TaskDisplayVo>>(taskClient.getDepartmentList(deptId, pageNo, pageSize));
    }

    @ApiOperation(value = "获取SOS病症列表", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/sos/diseases")
    public ResultVo<List<SosDiseaseVo>> getDisease(
            @RequestParam(value = "userId", required = true) Long userId) throws BaseException {
        List<SosDiseaseVo> disease = taskClient.getDisease(userId);
        return new ResultVo<>(disease);
    }

    @ApiOperation(value = "获取按任务类型区分的已发布任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "taskType", value = "任务类型", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "pageNo", value = "页码", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "条数", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/released")
    public ResultVo<List<TaskDisplayVo>> getReleasedList(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "taskType", required = true) String taskType,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize) {
        return new ResultVo<List<TaskDisplayVo>>(taskClient.getReleasedList(userId, taskType, pageNo, pageSize));
    }

    @ApiOperation(value = "获取按任务类型区分的已接收任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "taskType", value = "任务类型", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "pageNo", value = "页码", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "条数", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/received")
    public ResultVo<List<TaskDisplayVo>> getReceivedList(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "taskType", required = true) String taskType,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize) {
        return new ResultVo<List<TaskDisplayVo>>(taskClient.getReceivedList(userId, taskType, pageNo, pageSize));
    }

    @ApiOperation(value = "获取任务统计数据", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "类型(1:接收; 2:发布)", required = true, paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "dateTime", value = "时间节点", required = true, paramType = "query", dataType = "Date")
    })
    @GetMapping("/taskCount")
    public ResultVo<TaskCountResultVo> getTaskCountResultVo(
            @RequestParam(value = "type", required = true) Integer type,
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "dateTime", required = true) Date dateTime) {
        return new ResultVo<TaskCountResultVo>(taskClient.getTaskCountResultVo(type, userId, dateTime));
    }

    /**
     * 首页按类型区分的最新任务、未确认数量
     *
     * @param userId 用户id
     * @return 各种类型的最新任务、未确认数量
     */
    @ApiOperation(value = "首页按类型区分的最新任务、未确认数量", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/taskHome")
    public ResultVo<TaskAndConfirmStatusVo> getNewestTaskAndStatus(Long userId) {
        return new ResultVo<TaskAndConfirmStatusVo>(taskClient.getNewestTaskAndStatus(userId));
    }

    @ApiOperation(value = "首页搜索任务", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "searchName", value = "搜索关键字", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "taskType", value = "任务类型", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "搜索类型(1:接收; 2:发布)", required = true, paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageNo", value = "页码", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "pageSize", value = "条数", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/searchTask")
    public ResultVo<List<TaskDisplayVo>> getReceivedList(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "searchName", required = true) String searchName,
            @RequestParam(value = "taskType", required = false) String taskType,
            @RequestParam(value = "type", required = true) Integer type,
            @RequestParam(value = "pageNo", required = true) Long pageNo,
            @RequestParam(value = "pageSize", required = true) Long pageSize) {
        return new ResultVo<List<TaskDisplayVo>>(taskClient.getSearchTaskList(userId, searchName, taskType, type, pageNo, pageSize));
    }

    @ApiOperation(value = "SOS上报出诊人位置信息", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "taskId", value = "任务id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "longitude", value = "经度", required = true, paramType = "query", dataType = "BigDecimal"),
            @ApiImplicitParam(name = "latitude", value = "纬度", required = true, paramType = "query", dataType = "BigDecimal"),
            @ApiImplicitParam(name = "locationType", value = "地图类型(如果是腾讯/高德传参数:TX)", required = false, paramType = "query", dataType = "String"),
    })
    @PostMapping("sosReportLocation")
    public ResultVo<String> sosReportLocation(@RequestParam(value = "userId", required = true) Long userId,
                                              @RequestParam(value = "taskId", required = true) Long taskId,
                                              @RequestParam(value = "longitude", required = true) BigDecimal longitude,
                                              @RequestParam(value = "latitude", required = true) BigDecimal latitude,
                                              @RequestParam(value = "locationType", required = false) String locationType) {
        log.error("========================================================================================================================================");
        log.error("longitude = " + longitude + "==========latitude =" + latitude);
        String bool = "false";
        if (longitude == null || latitude == null) {
            throw new BaseRuntimeException(ServerStatusEnum.TASK_NOT_LOCATION);
        }
        Long sosTaskId = taskClient.getSosTaskId(taskId, userId);
        if (sosTaskId > 0) {
            JSONObject jsonObject = new JSONObject();
            Object obj = redisUtil.get("SOS_" + sosTaskId);
            if (null != obj) {
                jsonObject = JSONObject.parseObject(obj.toString());
                bool = jsonObject.getString("isReport");
            } else {
                bool = "true";
            }

            if (bool.equals("true")) {
                Map<String, Double> map = new HashMap<String, Double>();
                if (locationType.equals("TX")) {
                    map = MapConvertUtil.map_tx2bd(new Double(latitude.toString()), new Double(longitude.toString()));
                    jsonObject.put("longitude", map.get("lng"));
                    jsonObject.put("latitude", map.get("lat"));
                } else {
                    jsonObject.put("longitude", longitude);
                    jsonObject.put("latitude", latitude);
                }

                jsonObject.put("isReport", "true");
                String key = "SOS_" + sosTaskId;
                redisUtil.set(key, jsonObject.toString(), LOCATION);
                taskClient.sosReportLocation(userId, sosTaskId, new BigDecimal(Double.toString(map.get("lng"))), new BigDecimal(Double.toString(map.get("lat"))));
                log.error("SOS上报出诊人位置信息 key=" + key);
            }
        }
        return new ResultVo<String>(bool);
    }

    @ApiOperation(value = "SOS获取救护车位置信息", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "taskId", value = "任务id", required = true, paramType = "query", dataType = "Long")
    })
    @PostMapping("getEscortCarLocation")
    public ResultVo<JSONObject> getEscortCarLocation(@RequestParam(value = "userId", required = true) Long userId,
                                                     @RequestParam(value = "taskId", required = true) Long taskId) throws BaseException {
        JSONObject obj = new JSONObject();
        Object object = redisUtil.get("SOS_" + taskId);
        if (null == object) {
            TaskSOSStatusVo taskSOSStatusVo = taskClient.getSOSTaskStatusByPatientId(userId, taskId);
            if (null != taskSOSStatusVo) {
                obj.put("longitude", taskSOSStatusVo.getHospitalLongitude());
                obj.put("latitude", taskSOSStatusVo.getHospitalLatitude());
                obj.put("isReport", "true");
                String key = "SOS_" + taskId;
                redisUtil.set(key, obj.toString(), LOCATION);
            }

        } else {
            obj = JSONObject.parseObject(object.toString());
        }
        return new ResultVo<JSONObject>(obj);
    }

    @ApiOperation(value = "SOS救护车位置监控", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hospitalId", value = "医院id", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("sosAmbulanceLocation")
    public ResultVo<List<SosPlatformVo>> sosAmbulanceLocation(@RequestParam(value = "hospitalId", required = true) Long hospitalId) {
        List<SosPlatformVo> sosPlatformVoVos = taskClient.sosAmbulanceLocation(hospitalId);
        /*List<SosPlatformVo> list = sosPlatformVoVos.stream().map(detailVo -> {
            SosPlatformVo detail = new SosPlatformVo();
            BeanUtils.copyProperties(detailVo, detail);
            if (detailVo.getVisitLongitude() != null && detailVo.getVisitLatitude() != null) {
                Map<String, Double> map = MapConvertUtil.map_bd2tx(new Double(detailVo.getVisitLatitude().toString()), new Double(detailVo.getVisitLongitude().toString()));
                detail.setVisitLatitude(new BigDecimal(map.get("lat").toString()));
                detail.setVisitLongitude(new BigDecimal(map.get("lng").toString()));
            }
            if (detailVo.getPatientLongitude() != null && detailVo.getPatientLatitude() != null) {
                Map<String, Double> map = MapConvertUtil.map_bd2tx(new Double(detailVo.getPatientLatitude().toString()), new Double(detailVo.getPatientLongitude().toString()));
                detail.setPatientLatitude(new BigDecimal(map.get("lat").toString()));
                detail.setPatientLongitude(new BigDecimal(map.get("lng").toString()));
            }
            if (detailVo.getHospitalLongitude() != null && detailVo.getHospitalLatitude() != null) {
                Map<String, Double> map = MapConvertUtil.map_bd2tx(new Double(detailVo.getHospitalLatitude().toString()), new Double(detailVo.getHospitalLongitude().toString()));
                detail.setHospitalLatitude(new BigDecimal(map.get("lat").toString()));
                detail.setHospitalLongitude(new BigDecimal(map.get("lng").toString()));
            }
            return detail;
        }).collect(Collectors.toList());*/
        return new ResultVo<List<SosPlatformVo>>(sosPlatformVoVos);
    }

    /**
     * 获取车辆列表
     *
     * @return
     */
    @ApiOperation(value = "救护车列表", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "hospitalId", value = "医院id", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/sosAmbulanceList")
    public ResultVo<List<RemindAmbulanceVo>> getAmbulanceVoList(@RequestParam(value = "hospitalId", required = true) Long hospitalId) {
        List<RemindAmbulanceVo> ambulanceVoList = taskClient.getAmbulanceVoList(hospitalId);
        return new ResultVo<List<RemindAmbulanceVo>>(ambulanceVoList);
    }

    /**
     * 更新任务状态信息
     *
     * @param userId        用户id
     * @param taskId        任务id
     * @param confirmStatus 状态
     * @return 任务状态信息
     * @throws BaseException
     */
    @ApiOperation(value = "任务车辆记录", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "form", dataType = "Long"),
            @ApiImplicitParam(name = "taskId", value = "任务id", required = true, paramType = "form", dataType = "Long"),
            @ApiImplicitParam(name = "ambulanceId", value = "车辆ID", required = true, paramType = "form", dataType = "Long"),
            @ApiImplicitParam(name = "confirmStatus", value = "状态，字典00008", required = true, paramType = "form", dataType = "String")
    })
    @PostMapping("/saveTaskAmbulance")
    ResultVo<TaskStatusUpdateVo> saveTaskAmbulance(
            @RequestParam(value = "userId", required = true) Long userId,
            @RequestParam(value = "taskId", required = true) Long taskId,
            @RequestParam(value = "ambulanceId", required = true) Long ambulanceId,
            @RequestParam(value = "confirmStatus", required = true) String confirmStatus
    ) throws BaseException {
        TaskStatusUpdateVo updateVo = taskClient.saveTaskAmbulance(userId, taskId, ambulanceId, confirmStatus);
        return new ResultVo<>(updateVo);
    }

    /**
     * 发送视频请求
     *
     * @param taskId 任务id
     * @return
     */
    @ApiOperation(value = "发起视频请求", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "taskId", value = "任务ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "videoStatus", value = "请求状态", required = true, paramType = "query", dataType = "Integer"),
    })
    @GetMapping("/videoStatus")
    public ResultVo<Long> updateReportVideoTask(@RequestParam(value = "taskId", required = true) Long taskId,
                                                @RequestParam(value = "userId", required = true) Long userId,
                                                @RequestParam(value = "videoStatus", required = true) Integer videoStatus) {
        int i = taskClient.updateReportVideoTask(taskId, userId, videoStatus);
        return new ResultVo<>(Long.valueOf(i));
    }

    /**
     * 根据任务ID获取sos任务ID
     *
     * @param taskId 任务id
     * @return
     */
    @ApiOperation(value = "根据任务ID获取sos任务ID", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "taskId", value = "任务ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "userId", value = "用户ID", required = true, paramType = "query", dataType = "Long")
    })
    @GetMapping("/getSosTaskIdByTaskId")
    public ResultVo<Long> getSosTaskIdByTaskId(@RequestParam(value = "taskId", required = true) Long taskId,
                                               @RequestParam(value = "userId", required = true) Long userId) {
        return new ResultVo<>(taskClient.getSosTaskId(taskId, userId));
    }
}
